package multiplayer.lan;


import gui.gui2d.Promotion;

import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Observable;
import java.util.Observer;

import multiplayer.lan.utility.Message;
import utility.Point;

public class TcpServer extends Observable implements Runnable,TcpObject {
	public int port=8457;
	ServerSocket s;
	Socket so;
	ObjectOutputStream oos;
	InputStream is;
	ObjectInputStream ois;
	private boolean disable=false;
	private boolean connected=false;

	public boolean isConnected() {
		return connected;
	}
	public void setConnected(boolean connected) {
		this.connected = connected;
	}
	public boolean isDisable() {
		return disable;
	}
	public void setDisable(boolean disable) {
		this.disable = disable;
	}
	public TcpServer() {}
	
	@Override
	public void sendMovement(Point from , Point to) throws IOException{
		Move m = new Move(null,from, to);
		try {
			oos.writeObject(m);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			disable=true;
		}
	}
	@Override
	public Object receiveObject(){

		try {
			Object o = ois.readObject();

			return o;

		} catch (IOException | ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			setChanged();
			notifyObservers(new CloseConnection("Connessione persa"));
			disable=true;
		}
		return null;
	}
	@Override
	public void connect() throws IOException{
			s= new ServerSocket(port);
			so= s.accept();
			connected=true;
			System.out.println("Giocatore connesso");

			
		
	
	}
	public void setPort(int port) {
		this.port = port;
	}
	@Override
	public void closeConnection(){
		try {
			
			
			
			if(oos!=null){
			oos.flush();
			oos.close();
			}
			if(ois!=null){
				ois.close();
			}

			s.close();
			
			if(so!=null){
				so.close();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
	
	@Override
	public void run() {
		try {
			
			OutputStream os= so.getOutputStream();
			oos= new ObjectOutputStream(os);
			is = so.getInputStream();
			ois= new ObjectInputStream(is);
			while(!disable){
				Object m = receiveObject();
				setChanged();
				notifyObservers(m);
			}

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			disable=true;
		}finally{
			try {
				connected=false;
				s.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

	}

	@Override
	public void sendPromotion(Promotion p) {
		System.out.println(p);
		try {
			oos.writeObject(p);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	@Override
	public void sendMessage(String nome, String message) throws IOException {
		Message inf= new Message(nome, message);
		try {
			oos.writeObject(inf);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	@Override
	public void loadIp(String ip) {
		throw new UnsupportedOperationException("This can be used only on TcpClient instance");
		
	}
	@Override
	public void disable() {
		disable=true;
		
	}
	@Override
	public boolean isClosed() {
		return s.isClosed();
		
	}


}
